home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2003 November A / PCWK1103A.iso / ABBYY FineReader 7.0 PRO / data1.cab / gs_cmap.ps < prev    next >
Text File  |  2002-04-03  |  18KB  |  524 lines

  1. %    Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: gs_cmap.ps,v 1.11.2.4 2002/04/02 13:26:37 mpsuzuki Exp $
  14. % ProcSet for implementing CMap resources.
  15. % When this is run, systemdict is still writable.
  16.  
  17. % NOTE: Rearranged fonts are not implemented yet.
  18.  
  19. [
  20.    /CMERGE_DEBUG
  21.    /USE_CIDCHAR_AS_RANGE
  22. ] {dup where {pop pop} { currentdict exch false def pop } ifelse} forall
  23.  
  24. % ---------------- Public operators ---------------- %
  25.  
  26. /.rewriteTempMapsNotDef {
  27.   %
  28.   % Before building .CodeMapData from .TempMaps,
  29.   % we need to replace dst type codes in the notdef map with the value 3,
  30.   % which corresponds to CODE_VALUE_NOTDEF, see gxfcmap.h .
  31.   %
  32.   DEBUG { (rewriting TempMapsNotDef\n) print flush } if
  33.   .TempMaps 2 get
  34.   dup length 0 gt {
  35.     0 get
  36.     DEBUG { (...original...\n) print flush } if
  37.     1 5 2 index length 1 sub {
  38.       { 1 index exch get 2 3 put } stopped
  39.       { DEBUG { (cannot rewrite\n) print flush } if }
  40.       { DEBUG { (rewrite\n) print flush } if } ifelse
  41.     } for
  42.   } if
  43.   pop
  44.   DEBUG { (...FINISHED...\n) print } if
  45. } bind def
  46.  
  47. % composefont doesn't appear in CMap files -- it's documented in
  48. % the "PostScript Language Reference Manual Supplement".
  49. /composefont {        % <name> <cmap|cmapname> <fonts> composefont <font>
  50.   10 dict begin
  51.     /CMap 2 index dup type /dicttype ne { /CMap findresource } if def
  52.     /FDepVector 1 index cvlit def    % temporarily
  53.     /Encoding [ 0 1 FDepVector length 1 sub { } for ] def
  54.     /FDepVector [ 0 1 FDepVector length 1 sub {
  55.         % Stack: name cmap[name] fonts /FDepVector [ fonts... i
  56.       FDepVector 1 index get
  57.       dup type /dicttype ne {
  58.     dup /CIDFont resourcestatus {
  59.       pop pop /CIDFont
  60.     } {
  61.       /Font
  62.     } ifelse findresource
  63.       } if
  64.       exch CMap /FontMatrices get dup length 2 index gt {
  65.     exch get dup null eq { pop } { makefont } ifelse
  66.       } {
  67.     pop pop
  68.       } ifelse
  69.     } for ] readonly def
  70.     /FMapType 9 def
  71.     /FontMatrix matrix def
  72.     /FontName 3 index def
  73.     CMap /WMode .knownget { /WMode exch def } if
  74.     /FontType 0 def
  75.   pop pop currentdict end /Font defineresource
  76. } bind odef
  77.  
  78. % ---------------- CMap operators ---------------- %
  79.  
  80. 40 dict begin
  81.  
  82. % Our internal .CodeMapData structure closely mirrors the structures
  83. % defined in gxfcmap.h (q.v.).  () indicate a string, [] indicate an array,
  84. % ? indicates a Boolean, # indicates an integer, {} for grouping.
  85. %    [[(first) (last) ...]        % code space ranges
  86. %     [(prefix) (key_size,?is_range,value_type,value_size) (keys...)
  87. %       {(values...) | [value ...]} #font_index    % code mappings
  88. %      ...]
  89. %     <<same>>        % notdef mappings
  90. %    ]
  91. % FontMatrices is the array of matrices defined by begin/endusematrix.
  92. % All of the arrays and strings are read-only after they have been built.
  93. %
  94. % Note that the code in zfcmap.c that constructs the C structures from
  95. % the PostScript structures has intimate knowledge of the above format.
  96.  
  97. % ****** NOTE: The code currently only handles "well-behaved" CMaps:
  98. %    - CID values only (no bfchars), 16-bit
  99. %    - Entries (both code space and map) must be sorted
  100. %    - Only the last byte must vary in each map range, except for
  101. %    the identity mapping
  102.  
  103. % ------ Font-level operators ------ %
  104.  
  105. /begincmap {        % - begincmap -
  106.   /.CodeMapData [[] [] []] def
  107.   /FontMatrices [] def
  108.   /.FontIndex 0 def
  109.   /.TempMaps [20 dict 50 dict 50 dict] def
  110.   /CodeMap null def        % for .buildcmap
  111. } bind def
  112. /endcmap {        % - endcmap -
  113.   .rewriteTempMapsNotDef
  114.   DEBUG {
  115.     (*** defined charmap ***\n) print
  116.     .TempMaps 1 get {exch == (\t) print ==} forall
  117.     (*** undefined charmap ***\n) print
  118.     .TempMaps 2 get {exch == (\t) print ==} forall
  119.   } if
  120.   10 dict begin 0 1 2 {
  121.     /i exch def
  122.         % Append data from .TempMaps to .CodeMapData.
  123.     /t .TempMaps i get def
  124.     .CodeMapData i get length t { exch pop length add } forall
  125.     DEBUG { (requested array size ) print dup == } if
  126.     array /a exch def
  127.     a 0 .CodeMapData i get .putmore
  128.     0 1 t length 1 sub {
  129.       t exch get .putmore
  130.     } for pop pop
  131.     .CodeMapData i a put
  132.   } for end
  133.   currentdict /.TempMaps undef
  134.   /.CodeMapData .CodeMapData .endmap def
  135.   /FontMatrices FontMatrices .endmap def
  136. } bind def
  137.  
  138. /.putmore {        % <array> <i> <array2> .putmore <array> <i+len(array2)>
  139.   3 copy putinterval length add
  140. } bind def
  141.  
  142. /.endmap {        % <map> .endmap <map>
  143.   dup type /arraytype eq {
  144.     % This might be a shared read-only array inherited via usecmap.
  145.     % Don't try to update its elements if this is the case.
  146.     dup wcheck {
  147.       0 1 2 index length 1 sub {
  148.     2 copy 2 copy get .endmap put pop
  149.       } for readonly
  150.     } if
  151.   } {
  152.     dup type /stringtype eq { readonly } if
  153.   } ifelse
  154. } bind def
  155.  
  156. /.appendmap {        % -mark- <elt> ... <array#> .appendmap -
  157.   .TempMaps exch get counttomark 1 add 1 roll
  158.   ] 1 index length exch put
  159. } bind def
  160.  
  161. /begincodespacerange {    % <count> begincodespacerange -
  162.   pop mark
  163. } bind def
  164. /endcodespacerange {    % <code_lo> <code_hi> ... endcodespacerange -
  165.   0 .appendmap
  166. } bind def
  167.  
  168. /usecmap {        % <CMap_name> usecmap -
  169.   /CMap findresource dup
  170.         % Copy the top level of .CodeMapData
  171.   /.CodeMapData exch /.CodeMapData get copyarray def
  172.   /FontMatrices exch /FontMatrices get copyarray def
  173. } bind def
  174.  
  175. /usefont {        % <fontID> usefont -
  176.   /.FontIndex exch def
  177. } bind def
  178.  
  179. /beginusematrix {    % <fontID> beginusematrix -
  180.   FontMatrices wcheck not FontMatrices length 2 index le or {
  181.     FontMatrices length 1 index 1 add .max array
  182.     dup 0 FontMatrices putinterval
  183.     /FontMatrices exch def
  184.   } if
  185. } bind def
  186. /endusematrix {        % <matrix> endusematrix -
  187.   FontMatrices 3 1 roll put
  188. } bind def
  189.  
  190. % ------ Rearranged font operators ------ %
  191.  
  192. /beginrearrangedfont {    % <font_name> <font*> beginrearrangedfont -
  193.   10 dict begin
  194.   /.FontNames exch def
  195.   /.FontName exch def
  196.   begincmap
  197. } bind def
  198. /endrearrangedfont {    % - endrearrangedfont -
  199.   (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
  200.   FontName .FontNames 0 get findfont end definefont pop
  201. } bind def
  202.  
  203. % ------ Character name/code selector operators ------ %
  204.  
  205. /beginbfchar {        % <count> beginbfchar -
  206.   pop mark
  207. } bind def
  208. /endbfchar {        % <code> <to_code|charname> ... endbfchar
  209.   counttomark 2 idiv {
  210.     counttomark -2 roll        % process in correct order
  211.     .addbfchar
  212.   } repeat 1 .appendmap
  213. } bind def
  214.  
  215. /beginbfrange {        % <count> beginbfrange -
  216.   pop mark
  217. } bind def
  218. /endbfrange {        % <code_lo> <code_hi> <to_code|(charname*)> ...
  219.             %   endbfrange -
  220.   counttomark 3 idiv {
  221.     counttomark -3 roll        % process in correct order
  222.     dup type dup /arraytype eq exch /packedarraytype eq or {
  223.             % Array value, split up.
  224.       exch pop {
  225.             % Stack: code to_code|charname
  226.     1 index exch .addbfchar
  227.             % Increment the code.  As noted above, we require
  228.             % that only the last byte vary, but we still must
  229.             % mask it after incrementing, in case the last
  230.             % value was 0xff.
  231.             % Stack: code prefix params key value fontindex
  232.     6 -1 roll dup length string copy
  233.     dup dup length 1 sub 2 copy get 1 add 255 and put
  234.       } forall pop
  235.     } {
  236.             % Single value, handle directly.
  237.       .addbfrange
  238.     } ifelse
  239.   } repeat 1 .appendmap
  240. } bind def
  241.  
  242. /.addbfchar {        % <code> <to_code|charname> .addbfchar
  243.             %   <prefix> <params> <key> <value> <font_index>
  244.   1 index exch .addbfrange
  245. } bind def
  246. /.addbfrange {        % <code_lo> <code_hi> <to_code|charname>
  247.             %   .addbfrange <<same as .addbfchar>>
  248.   4 string dup 3
  249.   3 index type /nametype eq {
  250.     2 index 2 1 put % dst = CODE_VALUE_GLYPH, see gxfcmap.h .
  251.     4 -1 roll 1 array astore 4 1 roll 4
  252.   } {
  253.     2 index 2 2 put % dst = CODE_VALUE_CHARS, see gxfcmap.h .
  254.     3 index length
  255.   } ifelse put
  256.             % Stack: code_lo code_hi value params
  257.   3 index 3 index eq {
  258.             % Single value.
  259.     3 -1 roll pop exch () exch
  260.   } {
  261.             % Range.
  262.     dup 0 1 put dup 1 1 put
  263.     4 2 roll
  264.     dup dup length 1 sub 0 exch getinterval 5 1 roll    % prefix
  265.             % Stack: prefix value params code_lo code_hi
  266.     2 { exch dup length 1 sub 1 getinterval } repeat concatstrings
  267.     3 -1 roll
  268.   } ifelse
  269.   .FontIndex
  270. } bind def
  271.  
  272. % ------ CID selector operators ------ %
  273.  
  274. /begincidchar {        % <count> begincidchar -
  275.   pop mark
  276. } bind def
  277. /endcidchar {        % <code> <cid> ... endcidchar -
  278.   1 .endmapchars
  279. } bind def
  280.  
  281. /begincidrange {    % <count> begincidrange -
  282.   pop mark
  283. } bind def
  284. /endcidrange {        % <code_lo> <code_hi> <cid_base> ... endcidrange -
  285.   1 .endmapranges
  286. } bind def
  287.  
  288. /.endmapchars {         % -mark- <code> <cid> ... <map#> .endmapchars -
  289.   counttomark 1 add 1 roll
  290.   counttomark 2 idiv {
  291.     counttomark -2 roll         % process in correct order
  292.     exch        % <cid> <code>
  293.                 % Construct prefix, params, key, value, font_index
  294.     dup length 1 eq {   % 1-byte
  295.       <00 00 00 02> ()  % <prefix> <param> <null_key>
  296.     } {                 % N-byte
  297.       dup 0 1 getinterval exch  % make 1-byte prefix
  298.       4 string dup 0
  299.       USE_CIDCHAR_AS_RANGE {
  300.         <00 01 00 02>   % skelton for param
  301.       } {
  302.         <00 00 00 02>   % skelton for param
  303.       } ifelse
  304.       putinterval
  305.       exch              % <prefix> <param> <code>
  306.       dup length        % <prefix> <param> <code> N
  307.       1 sub             % <prefix> <param> <code> N-1
  308.       dup               % <prefix> <param> <code> N-1 N-1
  309.       3 index           % <prefix> <param> <code> N-1 N-1 <param>
  310.       exch              % <prefix> <param> <code> N-1 <param> N-1
  311.       0 exch            % <prefix> <param> <code> N-1 <param> 0 N-1
  312.       put               % <prefix> <param'> <code> N-1
  313.       1 exch            % <prefix> <param'> <code> 1 N-1
  314.       getinterval       % <prefix> <param'> <key>
  315.  
  316.       USE_CIDCHAR_AS_RANGE {
  317.         dup length 2 mul string % <key> <dkey>
  318.         dup                     % <key> <dkey> <dkey>
  319.         2 index                 % <key> <dkey> <dkey> <key>
  320.         0 exch putinterval      % <key> <dkey'>
  321.         dup                     % <key> <dkey'> <dkey'>
  322.         3 -1 roll               % <dkey'> <dkey'> <key>
  323.         dup length              % <dkey'> <dkey'> <key> N-1
  324.         exch putinterval        % <dkey''>
  325.       } if
  326.  
  327.     } ifelse
  328.  
  329.     4 -1 roll           % <prefix> <param'> <key> <cid>
  330.     .endmapvalue        % <prefix> <param'> <key> <hex_cid> <font_idx>
  331.     % prefix params keys value fontindex
  332.     counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item)
  333.        4 index 10 index eq      % compare prefix
  334.        4 index 10 index eq and  % compare params
  335.        1 index 7 index eq and   % compare fontindex
  336.         {
  337.           DEBUG { (merge! char\n) print } if
  338.           pop 4 2 roll pop pop
  339.            % prefix params keys value fontindex keys2 value2
  340.           5 -1 roll 3 -1 roll concatstrings
  341.            % prefix params value fontindex value2 keys'
  342.           4 -1 roll 3 -1 roll concatstrings
  343.            % prefix params fontindex keys' values'
  344.           3 -1 roll
  345.         } if
  346.      } if % end of 2 (or more) ranges
  347.     CMERGE_DEBUG {
  348.     ( prefix:) print 4 index =only
  349.     ( param:) print 3 index =only
  350.     ( key:) print 2 index =only
  351.     ( hex_cid:) print 1 index =only
  352.     ( font_idx:) print 0 index == flush
  353.     } if
  354.   } repeat
  355.   counttomark 2 add -1 roll .appendmap
  356. } bind def
  357.  
  358. /.endmapranges {    % -mark- <code_lo> <code_hi> <cid_base> ... <map#>
  359.             %   .endmapranges -
  360.   counttomark 1 add 1 roll
  361.   counttomark 3 idiv {
  362.     counttomark -3 roll        % process in correct order
  363.         % Construct prefix, params, key_lo, key_hi, value, font_index
  364.     3 1 roll    % <cid_base> <code_lo> <code_hi>
  365.         %        prefix    key
  366.         % 1-byte code:    ()    .
  367.         % 1-byte range:    ()    .
  368.         % N-byte code:    .    (*)
  369.         % N-byte range:    (*)    (*)
  370.     dup 2 index eq {    % <code_lo> == <code_hi>
  371.                    % 0: prefix_len for 1-byte code
  372.                    % 1: prefix_len for N-byte code
  373.        dup length 1 eq { 0 } { 1 } ifelse
  374.     } {            % <code_lo> != <code_hi>
  375.                  % calculate prefix_len for *-byte range
  376.        dup length 1 sub % <cid_base> <code_lo> <code_hi> <code_len-1>
  377.        0        % initial value for N
  378.        {        % <cid_base> <code_lo> <code_hi> (code_len-1)  N
  379.            dup 2 index ge { exit } if % if (N >= len - 1) exit
  380.            3 index 1 index get    % N-th byte of code_lo
  381.            3 index 2 index get    % N-th byte of code_hi
  382.            eq { 1 add } { exit } ifelse
  383.        } loop
  384.        exch pop     % discard <code_len-1>
  385.     } ifelse
  386.                 % cid_base code_lo code_hi prefix_len
  387.  
  388.     % Althogh Adobe CPSI with native CID/CMap support accept
  389.     % multi-dimensional range specification in notdef & cidrange
  390.     % (and CID is calculated as relative position in multi-dimensional
  391.     % range), but older CPSI & ATM cannot handle it.
  392.     % 
  393.     % GS accepts such specification, but it's recommended to keep
  394.     % from using this feature for notdef & cidrange.
  395.     % Following is a disabler of this feature.
  396.     % -------------------------------------------------------------
  397.     % counttomark 1 add index     % get map#
  398.     % 0 ne {            % if not codespacerange
  399.     %   1 index length         % get code length
  400.     %   1 index             % get prefix length
  401.     %   sub            % calculate key length
  402.     %   1 gt {            % if (key_len > 1),
  403.     %      (.endmapranges error) = flush
  404.     %      (multi-dimensional range specification is used out of codespacerange)
  405.     %      = flush
  406.     %      (/) =only
  407.     %      CMapName CMapName length string cvs =only
  408.     %      (: <) =only
  409.     %      2 index (%stdout) (w) file exch writehexstring
  410.     %      (> <) =only
  411.     %      1 index (%stdout) (w) file exch writehexstring
  412.     %      (>\n) =only flush
  413.     %      quit
  414.     %   } if
  415.     % } if
  416.     % -------------------------------------------------------------
  417.  
  418.     1 index exch 0 exch getinterval
  419.                 % cid_base code_lo code_hi prefix
  420.     dup length 3 index length exch sub
  421.                 % cid_base code_lo code_hi prefix range_len
  422.     dup 255 gt {
  423.        (too long coderange specification for current GS\n) print
  424.        signalerror
  425.     } if
  426.     <00 01 00 02> 4 string copy    % create initialized param
  427.     dup 0 4 -1 roll put        % put range_len into param
  428.  
  429.     % get key_hi
  430.     3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval
  431.  
  432.     % get key_lo
  433.     4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval
  434.  
  435.     % make "keys" (concatenated key_lo + key_hi)
  436.     exch concatstrings
  437.  
  438.     % 
  439.     4 -1 roll
  440.     .endmapvalue
  441.  
  442.         % See if we can merge with the previous value.
  443.         % The prefix, params, and font index must match.
  444.     % prefix params keys value fontindex
  445.     counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item)
  446.        4 index 10 index eq    % compare prefix
  447.        4 index 10 index eq and    % compare params
  448.        1 index 7 index eq and    % compare fontindex
  449.     {
  450.           DEBUG { (merge!\n) print } if
  451.       pop 4 2 roll pop pop
  452.            % prefix params keys value fontindex keys2 value2
  453.       5 -1 roll 3 -1 roll concatstrings
  454.            % prefix params value fontindex value2 keys'
  455.       4 -1 roll 3 -1 roll concatstrings
  456.            % prefix params fontindex keys' values'
  457.       3 -1 roll
  458.     } if
  459.      } if % end of 2 (or more) ranges
  460.   } repeat
  461.   counttomark 2 add -1 roll .appendmap
  462. } bind def
  463.  
  464. /.endmapvalue {        % <cid> .endmapvalue (hi,lo) .FontIndex
  465.   2 string dup 0 3 index -8 bitshift put    % value
  466.   dup 1 4 -1 roll 255 and put
  467.   .FontIndex        % font_index
  468. } bind def
  469.  
  470. % ------ notdef operators ------ %
  471.  
  472. /beginnotdefchar {    % <count> beginnotdefchar -
  473.   pop mark
  474. } bind def
  475. /endnotdefchar {    % <code> <cid> ... endnotdefchar -
  476.   2 .endmapchars
  477. } bind def
  478.  
  479. /beginnotdefrange {    % <count> beginnotdefrange -
  480.   pop mark
  481. } bind def
  482. /endnotdefrange {    % <code_lo> <code_hi> <cid> ... endnotdefrange -
  483.   2 .endmapranges
  484. } bind def
  485.  
  486. % ---------------- Resource category definition ---------------- %
  487.  
  488. currentdict end
  489.  
  490. languagelevel exch 2 .setlanguagelevel
  491.  
  492. /CMap /Generic /Category findresource dup length dict .copydict
  493. dup /InstanceType /dicttype put
  494. dup /DefineResource {
  495.         % The AdobePS5 Windows driver emits code that attempts to
  496.         % create CMaps without the required CMapName entry.
  497.         % Work around this here.
  498.   dup /CMapName known not {
  499.     dup wcheck not {
  500.       .currentglobal exch dup wcheck .setglobal
  501.       dup length dict .copydict exch .setglobal
  502.     } if
  503.     dup gcheck 2 index gcheck not and {
  504.       exch .currentglobal exch true .setglobal
  505.       dup length string copy exch .setglobal exch
  506.     } if dup /CMapName 3 index put
  507.   } if
  508.   dup /CodeMap get null eq { .buildcmap } if
  509.   /Generic /Category findresource /DefineResource get exec
  510. } put
  511. /Category defineresource pop
  512.     % We might have loaded CID font support already.
  513. /CIDInit /ProcSet 2 copy { findresource } .internalstopped
  514.     % An interior `stopped' might have reset VM allocation to local.
  515. true .setglobal
  516.  { pop pop 3 -1 roll }
  517.  { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
  518. ifelse exch defineresource pop
  519.  
  520. .setlanguagelevel
  521.